﻿package 
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;	
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.filters.ColorMatrixFilter;
	import flash.geom.ColorTransform;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.media.Camera;
	import flash.media.Video;
	import flash.text.TextField;

	/*
	 * coded by moka 2009 / 07/ 25 
	 * name : moka's toonstyle
	 * installation : one webcam (需要一台視訊)
	 * blog : http://designplusplus.blogspot.com/
	 */
	
	public class Main extends Sprite 
	{		
		private var bg:Bitmap;
		private var cam:Camera;
		private var vid:Video;
		private var grayBuffer:BitmapData;
		private var colorBuffer:BitmapData;		
		private var colorStep:uint;
		private var colorPalette:Array;
		
		public function Main():void 
		{			
			// stage setting (場景不變形)
			stage.scaleMode = "noScale";
			
			// image initialization (點陣圖初始化)
			bg = addChild(new Bitmap(new BitmapData(640, 480, false, 0))) as Bitmap;
			grayBuffer = new BitmapData(160, 120, false);
			colorBuffer = new BitmapData(160, 120, false);
			
			// camera setting (視訊初始化)
			cam = Camera.getCamera();
			cam.setMode(160, 120, 15);
			vid = new Video(160, 120);
			vid.attachCamera(cam);		
			
			// information (資訊顯示)
			var info:TextField = addChild(new TextField()) as TextField;
			info.textColor = 0xFFFFFF;
			info.x = 15;
			info.y = 280;
			info.width = 300;
			info.text = "you can change color by clicking the mouse"
			
			// Moka's work 2009
			var moka:TextField = addChild(new TextField()) as TextField
			moka.x = 15;
			moka.y = 255;
			moka.width = 300;
			moka.htmlText = "<font color='#FFFFFF' size='32'>Moka's work</font>";
			
			colorStep = 6;
			colorPalette = new Array();
			for (var i:uint = 0; i < colorStep; i++ )
				colorPalette.push(0xFFFFFFFF * Math.random() );
			
			//event registration (事件註冊)
			stage.addEventListener(MouseEvent.CLICK, function onClick(e:MouseEvent):void {
				for (var i:uint = 0; i < colorStep; i++ )
					colorPalette[i] = (0xFFFFFFFF * Math.random() );
			})
			stage.addEventListener(Event.ENTER_FRAME, onProcess)
		}		
		
		private function onProcess(e:Event):void {	
			
			// create gray video image
			grayBuffer.draw(vid);
			grayBuffer.applyFilter(grayBuffer, grayBuffer.rect, new Point, new ColorMatrixFilter(
			[0.3, 0.59, 0.11, 0, 0,
             0.3, 0.59, 0.11, 0, 0,
             0.3, 0.59, 0.11, 0, 0,
             0, 0, 0, 1, 0]));
			
			// draw different color on image
			var tmpBmp:BitmapData = new BitmapData(160,120,false);			

			for (var i:uint = colorStep; i > 0; i--) {
				tmpBmp.draw(grayBuffer);
				// distinguish the image of grayBuffer between different levels, and draw different colors on each one. 
				tmpBmp.threshold(tmpBmp, tmpBmp.rect, new Point, "<", 0xFF000000 + uint(0x010101 * (255 * (colorStep - i + 1) / colorStep)), 0xFFFFFF);
				tmpBmp.threshold(tmpBmp, tmpBmp.rect, new Point, ">", 0, colorPalette[i-1]);
				
				if (i == colorStep)
					colorBuffer.draw(tmpBmp);
				else
					colorBuffer.draw(tmpBmp, new Matrix, new ColorTransform, "screen");		
			}
			
			bg.bitmapData.draw(colorBuffer, new Matrix(4, 0, 0, 4, 0));				
			tmpBmp.dispose();
		}
	}		
}